﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace SisCRA
{
    public class Log
    {
        #region -Constants-

        private const string LOG_DIR_NAME = @"\SisCRA\";
        private const string LOG_FILE_NAME = "SisCRA.log";

        #endregion

        #region -Private Attributes-

        private static Log instance;

        private string path;
        private DirectoryInfo dirInfo;
        private FileInfo fileInfo;

        #endregion

        #region -Constructor-

        /// <summary>
        /// Construtor padrão.
        /// </summary>
        private Log()
        {
            // Path.
            this.path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);

            // DirectoryInfo.
            this.dirInfo = new DirectoryInfo(path + LOG_DIR_NAME);

            //FileInfo.
            this.fileInfo = new FileInfo(path + LOG_DIR_NAME + LOG_FILE_NAME);
        }

        #endregion

        #region -Singleton-

        /// <summary>
        /// Retorna uma instância da classe Log.
        /// </summary>
        public static Log Instance
        {
            get 
            {
                if (instance == null)
                {
                    instance = new Log();
                }
                
                return instance;
            }
        }

        #endregion

        #region -Public Methods-

        /// <summary>
        /// Método que escreve a exceção no arquivo de logs.
        /// </summary>
        /// <param name="exception">Exceção gerada pela aplicação</param>
        public void Error(Exception exception)
        {
            try
            {
                WriteLog(exception);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion

        #region -Private Methods-

        /// <summary>
        /// Cria a pasta e o arquivo de logs.
        /// </summary>
        /// <returns>FileStream do arquivo criado</returns>
        private FileStream CreateDirectoryAndFile()
        {
            try
            {
                if (!dirInfo.Exists)
                {
                    dirInfo.Create();
                    dirInfo.Attributes = FileAttributes.Hidden;
                }

                return new FileStream(path + LOG_DIR_NAME + LOG_FILE_NAME, FileMode.Append, FileAccess.Write);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// Formata e escreve a exceção no arquivo de logs.
        /// </summary>
        /// <param name="exception">Exceção gerada pela aplicação</param>
        private void WriteLog(Exception exception)
        {
            try
            {
                using (FileStream fs = CreateDirectoryAndFile())
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        sw.WriteLine("[{0}] - {1}", DateTime.Now, exception.Message);
                        sw.WriteLine("{0} {1}", exception.StackTrace, sw.NewLine);
                    }
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #endregion
    }
}
